
//--------------------------------------------------------------------------------------------------------------------
AttachWindowLoadEventHandler();

//--------------------------------------------------------------------------------------------------------------------
// Attach an event handler to manage window load message.
function AttachWindowLoadEventHandler()
{
	try
	{
		if (window.addEventListener)
			window.addEventListener("load", MakeTree, false);
		else if (window.attachEvent)
			window.attachEvent("onload", MakeTree);
	}
	catch (e)
	{
		alert('AttachWindowLoadEventHandler: ' + e);
	}
}

//--------------------------------------------------------------------------------------------------------------------
// Change the state (collapse/expand) of the entire tree or a part of the tree.
function ChangeState(tree, className, stopAt)
{
	if (tree.childNodes && (tree.childNodes.length > 0))
	{
		for (var i = 0; i < tree.childNodes.length; i++)
		{
			var item = tree.childNodes[i];
			if (item.nodeName == "LI")
			{
				var containsTree = false;
				for (var j = 0; j <item.childNodes.length; j++)
				{
					var subItem = item.childNodes[j];
					if (subItem.nodeName == "UL")
					{
						containsTree = true;
						ChangeState(subItem, className);
					}
				}
				
				if (containsTree)
					item.className = className;
			}
		}
	}
}

//--------------------------------------------------------------------------------------------------------------------
// Collapse the tree specified by its client ID.
function CollapseTree(id)
{
	var tree = document.getElementById(id);
	if (tree != null)
		ChangeState(tree, "Collapse");
}

//--------------------------------------------------------------------------------------------------------------------
// Expand the tree specified by its client ID.
function ExpandTree(id)
{
	var tree = document.getElementById(id);
	if (tree != null)
		ChangeState(tree, "Expand");
}

//--------------------------------------------------------------------------------------------------------------------
// Write the style for the tree to the window.
function GetSelectTreeStyles(imagePath)
{
	var styles =
		"<style>\n" +
		"ul.SelectTree li\n" +
		"{\n" +
		"	list-style: none;\n" +
		"}\n" +
		"ul.SelectTree, ul.SelectTree ul, ul.SelectTree li\n" +
		"{\n" +
		"	margin-left: 10px;\n" +
		"	padding: 0px;\n" +
		"}\n" +
		"ul.SelectTree li .Leaf\n" +
		"{\n" +
		"	padding-left: 15px;\n" +
		"}\n" +
		"ul.SelectTree li.Expand .Leaf\n" +
		"{\n" +
		"	cursor: hand;\n" +
		"	background: url(" + imagePath + "/minus.gif) center left no-repeat;\n" +
		"}\n" +
		"ul.SelectTree li.Collapse .Leaf\n" +
		"{\n" +
		"	cursor: hand;\n" +
		"	background: url(" + imagePath + "/plus.gif) center left no-repeat;\n" +
		"}\n" +
		"ul.SelectTree li.Node .Leaf\n" +
		"{\n" +
		"	cursor: default;\n" +
		"	background: url(" + imagePath + "/clear.gif) center left no-repeat;\n" +
		"}\n" +
		"ul.SelectTree li.Expand ul\n" +
		"{\n" +
		"	display: block;\n" +
		"}\n" +
		"ul.SelectTree li.Collapse ul\n" +
		"{\n" +
		"	display: none;\n" +
		"}\n" +
		"</style>\n";
	return styles;
}

//--------------------------------------------------------------------------------------------------------------------
// Manage the cascading of check-state.
function ManageCascade(startingItem, item, checked)
{
	if (ShouldTreeSelectionCascade(startingItem.itemType))
	{
		for (var i = 0; i < item.childNodes.length; i++)
		{
			switch (item.childNodes[i].nodeName)
			{
				case "UL":
					for (var j = 0; j < item.childNodes[i].childNodes.length; j++)
						ManageCascade(startingItem, item.childNodes[i].childNodes[j], checked);
					break;
				case "INPUT":
					item.childNodes[i].checked = checked;
					break;
			}
		}
	}
}

//--------------------------------------------------------------------------------------------------------------------
// Manage activites related to making a selection (via the checkbox).
function ManageSelection(item, checked)
{
	ManageCascade(item, item, checked);
}

//--------------------------------------------------------------------------------------------------------------------
// The hierarchical representation is expressed in terms of the UL element wherein such elements are given the class
// name "MakeTree". Parse such elements and apply styles to them to render them the tree look.
function MakeTree()
{
	try
	{
		var ulList = document.getElementsByTagName("ul");
		for (var i = 0; i < ulList.length; i++)
			if (ulList[i].className == "SelectTree")
				ConvertToTree(ulList[i]);
	}
	catch (e)
	{
		alert('MakeTree: ' + e);
	}
}

//--------------------------------------------------------------------------------------------------------------------
// Convert the appearance of an UL element hierarchy to that of a tree control. Note that this simply implies applying
// appropriate styles to each node in that hierarchy.
function ConvertToTree(ul)
{
	if (ul.childNodes && (ul.childNodes.length > 0))
	{
		for (var i = 0; i < ul.childNodes.length; i++)
		{
			var item = ul.childNodes[i];
			if (item.nodeName == "LI")
			{
				var containsTree = false;
				for (var j = 0; j < item.childNodes.length; j++)
				{
					var subItem = item.childNodes[j];
					if (subItem.nodeName == "UL")
					{
						containsTree = true;
						ConvertToTree(subItem);
					}
				}
				
				var span = document.createElement("SPAN");
				var nodeText = '\u00A0'; // space.
				span.className = "Leaf";
				if (containsTree)
				{
					if ((item.className == null) || (item.className == ""))
						item.className = "Collapse";

					if (item.firstChild.nodeName == "#text")
					{
						nodeText += item.firstChild.nodeValue;
						item.removeChild(item.firstChild);
					}

					span.onclick = function ()
					{
						this.parentNode.className = (this.parentNode.className == "Expand") ? "Collapse" : "Expand";
						return false;
					}
				}
				else
					item.className = "Node";

				span.appendChild(document.createTextNode(nodeText));
				item.insertBefore(span, item.firstChild);
			}
		}
	}
}

// --- EOF ---

